package com.stx.jeepay.merchant.controller;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.stx.jeepay.core.entity.SysRoleEntity;
import com.stx.jeepay.core.entity.SysUserRoleRelaEntity;
import com.stx.jeepay.core.enums.ApiCodeEnum;
import com.stx.jeepay.core.enums.CS;
import com.stx.jeepay.core.expection.BizException;
import com.stx.jeepay.core.model.ApiPageRes;
import com.stx.jeepay.core.model.ApiRes;
import com.stx.jeepay.core.service.SysRoleEntRelaService;
import com.stx.jeepay.core.service.SysRoleService;
import com.stx.jeepay.core.service.SysUserRoleRelaService;
import com.stx.jeepay.core.utils.StringKit;
import com.stx.jeepay.merchant.service.AuthService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@Api(tags = "系统管理（用户角色）")
@RestController
@RequestMapping("api/sysRoles")
public class SysRoleController extends CommonCtrl {
    @Autowired
    SysRoleService sysRoleService;
    @Autowired
    SysUserRoleRelaService sysUserRoleRelaService;
    @Autowired
    private AuthService authService;
    @Autowired
    private SysRoleEntRelaService sysRoleEntRelaService;

    @ApiOperation("角色列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "iToken", value = "用户身份凭证", required = true, paramType = "header"),
            @ApiImplicitParam(name = "pageNumber", value = "分页页码", dataType = "int", defaultValue = "1"),
            @ApiImplicitParam(name = "pageSize", value = "分页条数（-1时查全部数据）", dataType = "int", defaultValue = "20"),
            @ApiImplicitParam(name = "roleId", value = "角色ID, ROLE_开头"),
            @ApiImplicitParam(name = "roleName", value = "角色名称")
    })
    @PreAuthorize("hasAnyAuthority( 'ENT_UR_ROLE_LIST', 'ENT_UR_USER_UPD_ROLE' )")
    @GetMapping("")
    public ApiPageRes<SysRoleEntity> list() {
        SysRoleEntity queryObject = getObject(SysRoleEntity.class);

        LambdaQueryWrapper<SysRoleEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRoleEntity::getSysType, CS.SYS_TYPE.MCH);
        queryWrapper.eq(SysRoleEntity::getBelongInfoId,getCurrentMchNo());

        if (StringUtils.isNotEmpty(queryObject.getRoleName())){
            queryWrapper.like(SysRoleEntity::getRoleName,queryObject.getRoleName());
        }

        if (StringUtils.isNotEmpty(queryObject.getRoleId())){
            queryWrapper.like(SysRoleEntity::getRoleId,queryObject.getRoleId());
        }
        queryWrapper.orderByDesc(SysRoleEntity::getUpdatedAt);

        IPage<SysRoleEntity> pages = sysRoleService.page(getIPage(true), queryWrapper);
        return ApiPageRes.pages(pages);
    }

    @ApiOperation("角色详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "iToken", value = "用户身份凭证", required = true, paramType = "header"),
            @ApiImplicitParam(name = "recordId", value = "角色ID, ROLE_开头", required = true)
    })
    @PreAuthorize("hasAuthority( 'ENT_UR_ROLE_EDIT' )")
    @GetMapping("/{recordId}")
    public ApiRes detail(@PathVariable("recordId") String recordId) {
        SysRoleEntity sysRole = sysRoleService.getOne(new LambdaQueryWrapper<SysRoleEntity>()
                .eq(SysRoleEntity::getRoleId,recordId)
                .eq(SysRoleEntity::getBelongInfoId,getCurrentMchNo()));
        if (sysRole == null) {
            throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SELETE);
        }
        return ApiRes.ok(sysRole);
    }

    @ApiOperation("添加角色信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "iToken", value = "用户身份凭证", required = true, paramType = "header"),
            @ApiImplicitParam(name = "roleName", value = "角色名称", required = true),
            @ApiImplicitParam(name = "entIdListStr", value = "权限信息集合，eg：[str1,str2]，字符串列表转成json字符串，若为空，则创建的角色无任何权限")
    })
    @PreAuthorize("hasAuthority( 'ENT_UR_ROLE_ADD' )")
    @PostMapping("")
    public ApiRes add() {
        SysRoleEntity sysRole = getObject(SysRoleEntity.class);
        String roleId = "ROLE_" + StringKit.getUUID(6);
        sysRole.setRoleId(roleId);
        sysRole.setSysType(CS.SYS_TYPE.MCH); //后台系统
        sysRole.setBelongInfoId(getCurrentUser().getSysUser().getBelongInfoId());
        sysRoleService.save(sysRole);

        //权限信息集合
        String entIdListStr =  getValString("entIdListStr");

        //如果包含： 可分配权限的权限 && entIdListStr 不为空
        if(getCurrentUser().getAuthorities().contains(new SimpleGrantedAuthority("ENT_UR_ROLE_DIST"))
                && StringUtils.isNotEmpty(entIdListStr)){
            List<String> entIdList = JSONArray.parseArray(entIdListStr, String.class);

            sysRoleEntRelaService.resetRela(roleId, entIdList);
        }

        return ApiRes.ok();
    }

    @ApiOperation("更新角色信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "iToken", value = "用户身份凭证", required = true, paramType = "header"),
            @ApiImplicitParam(name = "recordId", value = "角色ID, ROLE_开头", required = true),
            @ApiImplicitParam(name = "roleName", value = "角色名称", required = true),
            @ApiImplicitParam(name = "entIdListStr", value = "权限信息集合，eg：[str1,str2]，字符串列表转成json字符串，若为空，则创建的角色无任何权限")
    })
    @PreAuthorize("hasAuthority( 'ENT_UR_ROLE_EDIT' )")
    @PutMapping("/{recordId}")
    public ApiRes update(@PathVariable("recordId") String recordId) {
        SysRoleEntity sysRole = getObject(SysRoleEntity.class);
        LambdaUpdateWrapper<SysRoleEntity> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SysRoleEntity::getRoleId, recordId);
        updateWrapper.eq(SysRoleEntity::getBelongInfoId, getCurrentMchNo());
        sysRoleService.update(sysRole, updateWrapper);
        //权限信息集合
        String entIdListStr =  getValString("entIdListStr");
        //如果包含： 可分配权限的权限 && entIdListStr 不为空
        if(getCurrentUser().getAuthorities().contains(new SimpleGrantedAuthority("ENT_UR_ROLE_DIST"))
                && StringUtils.isNotEmpty(entIdListStr)){
            List<String> entIdList = JSONArray.parseArray(entIdListStr, String.class);

            sysRoleEntRelaService.resetRela(recordId, entIdList);

            List<Long> sysUserIdList = new ArrayList<>();
            sysUserRoleRelaService.list(new LambdaQueryWrapper<SysUserRoleRelaEntity>()
                    .eq(SysUserRoleRelaEntity::getRoleId, recordId))
                    .stream().forEach(item -> sysUserIdList.add(item.getUserId()));

            //查询到该角色的人员， 将redis更新
            authService.refAuthentication(sysUserIdList);
        }

        return ApiRes.ok();
    }

    @ApiOperation("删除角色")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "iToken", value = "用户身份凭证", required = true, paramType = "header"),
            @ApiImplicitParam(name = "recordId", value = "角色ID, ROLE_开头", required = true)
    })
    @PreAuthorize("hasAuthority('ENT_UR_ROLE_DEL')")
    @DeleteMapping("/{recordId}")
    public ApiRes del(@PathVariable("recordId") String recordId) {
        SysRoleEntity sysRole = sysRoleService.getOne(new LambdaQueryWrapper<SysRoleEntity>()
                .eq(SysRoleEntity::getRoleId, recordId)
                .eq(SysRoleEntity::getBelongInfoId, getCurrentMchNo()));
        if (sysRole == null) {
            throw new BizException(ApiCodeEnum.SYS_OPERATION_FAIL_SELETE);
        }

        if(sysUserRoleRelaService.count(new LambdaQueryWrapper<SysUserRoleRelaEntity>().eq(SysUserRoleRelaEntity::getRoleId, recordId)) > 0){
            throw new BizException("当前角色已分配到用户， 不可删除！");
        }
        sysRoleService.removeRole(recordId);
        return ApiRes.ok();
    }
}
